﻿using System;
using System.Collections.Generic;
using System.Linq;

// SDD# - Software Defined Devices in C# for Linux and Windows
// MenuSystem - MenuSystem class and MenuItem objects
// (c) 2014-2015 Chris Burri. MIT License applies. 
// See http://niston.wordpress.com

namespace sdd.subsystems.ui
{
    public class MenuSystem : IEnumerable<MenuItem>
    {
        private List<MenuItem> _MenuItems;

        public event EventHandler InitializeMenuSystem;
           
        public MenuSystem()
        {
            _MenuItems = new List<MenuItem>();
        }

        ~MenuSystem()
        {
            Clear();
        }

        public MenuItem Menu(string itemName, List<MenuItem> searchRoot = null)
        {
            if (searchRoot == null) { searchRoot = _MenuItems; }

            foreach (MenuItem item in searchRoot)
            {
                if (item.Name == itemName)
                {
                    return item;
                }

                if (item.SubItems.Count != 0)
                {
                    MenuItem ret = Menu(itemName, item.SubItems);
                    if (ret != null) { return ret; }
                }
            }
            return null;
        }

        public void Register(MenuItem newItem)
        {
            _MenuItems.Add(newItem);
        }

        public bool Register(MenuItem newItem, MenuItem parentItem, List<MenuItem> searchRoot = null)
        {
            if (searchRoot == null) { searchRoot = _MenuItems; }

            foreach (MenuItem item in searchRoot)
            {
                if (item.Name == parentItem.Name)
                {
                    if (!item.SubItems.Contains(newItem))
                    {
                        item.SubItems.Add(newItem);
                        return true;
                    }
                    else
                    {
                        // already exists
                        return false;
                    }
                }
                if (item.SubItems.Count != 0)
                {
                    // recursively try to register with subitem's subitems
                    bool Ret = Register(newItem, parentItem, item.SubItems);
                    if (Ret) { return true; }
                }
            }
            return false;
        }

        public bool Unregister(MenuItem itemToRemove, List<MenuItem> searchRoot = null)
        {
            if (searchRoot == null) { searchRoot = _MenuItems; }

            foreach (MenuItem item in searchRoot)
            {
                if (item.Name == itemToRemove.Name)
                {
                    searchRoot.Remove(item);
                    return true;
                }

                if (item.SubItems.Count != 0)
                {
                    bool ret = Unregister(itemToRemove, item.SubItems);
                    if (ret) { return true; }
                }
            }
            return false;
        }

        public void Clear(List<MenuItem> menuRoot = null)
        {
            if (menuRoot == null) { menuRoot = _MenuItems; }

            foreach (MenuItem item in menuRoot)
            {
                if (item.SubItems.Count != 0)
                {
                    Clear(item.SubItems);
                }

                item.Parent = null;
            }
            menuRoot.Clear();
        }

        public int Count { get { return _MenuItems.Count(); } }

        private int CountItems(bool countRecursive = true, List<MenuItem> countRoot = null)
        {
            int count = 0;
            if (countRoot == null) { countRoot = _MenuItems; }

            foreach (MenuItem item in countRoot)
            {
                count += 1;
                if (countRecursive)
                {
                    if (item.SubItems.Count != 0)
                    {
                        count += CountItems(countRecursive, item.SubItems);
                    }
                }
            }
            return count;
        }

        public IEnumerator<MenuItem> GetEnumerator()
        {
            return _MenuItems.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

}
